# -*- coding: utf-8 -*-
"""
乒乓球培训管理系统 - 球台控制器

球台相关的业务逻辑处理
包括CRUD操作、状态管理、使用统计等
"""

from datetime import datetime, date, timedelta
from flask import current_app
from flask_login import current_user
from sqlalchemy import and_, or_, func
from app import db
from app.models.table import Table
from app.models.campus import Campus
from app.models.reservation import Reservation


class TableController:
    """球台控制器类"""

    @staticmethod
    def get_table_list(page=1, per_page=10, keyword=None, campus_id=None,
                      status=None, sort_by='created_at_desc'):
        """
        获取球台列表（分页）

        Args:
            page: 页码
            per_page: 每页数量
            keyword: 搜索关键词
            campus_id: 校区ID筛选
            status: 状态筛选
            sort_by: 排序方式

        Returns:
            tuple: (分页对象, 总数)
        """
        query = Table.query.filter(Table.status != 'deleted')

        # 权限控制：校区管理员只能看到自己校区的球台
        if current_user.is_campus_admin() and current_user.campus_id:
            query = query.filter(Table.campus_id == current_user.campus_id)

        # 关键词搜索
        if keyword:
            query = query.filter(
                or_(
                    Table.name.contains(keyword)
                )
            )

        # 校区筛选
        if campus_id:
            query = query.filter(Table.campus_id == campus_id)

        # 状态筛选
        if status:
            query = query.filter(Table.status == status)

        # 排序
        if sort_by == 'created_at_desc':
            query = query.order_by(Table.created_at.desc())
        elif sort_by == 'created_at_asc':
            query = query.order_by(Table.created_at.asc())
        elif sort_by == 'name_asc':
            query = query.order_by(Table.name.asc())
        elif sort_by == 'name_desc':
            query = query.order_by(Table.name.desc())

        pagination = query.paginate(
            page=page,
            per_page=per_page,
            error_out=False
        )

        return pagination, pagination.total

    @staticmethod
    def get_table_by_id(table_id):
        """
        根据ID获取球台

        Args:
            table_id: 球台ID

        Returns:
            Table: 球台对象或None
        """
        table = Table.query.filter(
            and_(Table.id == table_id, Table.status != 'deleted')
        ).first()

        # 权限检查：校区管理员只能访问自己校区的球台
        if table and current_user.is_campus_admin():
            if current_user.campus_id != table.campus_id:
                return None

        return table

    @staticmethod
    def create_table(form_data):
        """
        创建球台

        Args:
            form_data: 表单数据

        Returns:
            tuple: (是否成功, 球台对象或错误信息)
        """
        try:
            # 权限检查：校区管理员只能在自己的校区创建球台
            campus_id = form_data['campus_id']
            if current_user.is_campus_admin():
                if current_user.campus_id != campus_id:
                    return False, "您只能在自己管理的校区创建球台"

            # 检查校区是否存在
            campus = Campus.query.get(campus_id)
            if not campus:
                return False, "选择的校区不存在"

            # 创建球台对象
            table = Table(
                name=form_data['name'],
                campus_id=campus_id,
                status=form_data['status'] if form_data.get('is_active', True) else 'disabled'
            )

            db.session.add(table)
            db.session.commit()
            return True, table

        except Exception as e:
            db.session.rollback()
            current_app.logger.error(f"Create table error: {str(e)}")
            return False, "创建球台失败，请重试"

    @staticmethod
    def update_table(table, form_data):
        """
        更新球台

        Args:
            table: 球台对象
            form_data: 表单数据

        Returns:
            tuple: (是否成功, 错误信息)
        """
        try:
            # 权限检查：校区管理员只能编辑自己校区的球台
            if current_user.is_campus_admin():
                if current_user.campus_id != table.campus_id:
                    return False, "您只能编辑自己校区的球台"

            # 如果是超级管理员且要修改校区
            if current_user.is_super_admin() and form_data['campus_id'] != table.campus_id:
                new_campus = Campus.query.get(form_data['campus_id'])
                if not new_campus:
                    return False, "目标校区不存在"
                table.campus_id = form_data['campus_id']

            # 更新球台信息
            table.name = form_data['name']
            table.status = form_data['status'] if form_data.get('is_active', True) else 'disabled'
            table.updated_at = datetime.now()

            db.session.commit()
            return True, None

        except Exception as e:
            db.session.rollback()
            current_app.logger.error(f"Update table error: {str(e)}")
            return False, "更新球台失败，请重试"

    @staticmethod
    def delete_table(table_id):
        """
        删除球台（软删除）

        Args:
            table_id: 球台ID

        Returns:
            tuple: (是否成功, 错误信息)
        """
        try:
            table = TableController.get_table_by_id(table_id)
            if not table:
                return False, "球台不存在或无权限访问"

            # 检查是否有活跃预约
            today = date.today()
            active_reservations = Reservation.query.filter(
                and_(
                    Reservation.table_id == table_id,
                    Reservation.status.in_(['confirmed', 'pending']),
                    Reservation.reservation_date >= today
                )
            ).count()

            if active_reservations > 0:
                return False, f"球台还有{active_reservations}个活跃预约，无法删除"

            # 执行软删除
            table.status = 'disabled'

            db.session.commit()
            return True, None

        except Exception as e:
            db.session.rollback()
            current_app.logger.error(f"Delete table error: {str(e)}")
            return False, "删除球台失败，请重试"

    @staticmethod
    def update_table_status(table_id, new_status):
        """
        更新球台状态

        Args:
            table_id: 球台ID
            new_status: 新状态

        Returns:
            tuple: (是否成功, 错误信息)
        """
        try:
            table = TableController.get_table_by_id(table_id)
            if not table:
                return False, "球台不存在或无权限访问"

            valid_statuses = ['available', 'maintenance', 'disabled']
            if new_status not in valid_statuses:
                return False, "无效的状态值"

            # 如果设置为维护或禁用，检查是否有进行中的预约
            if new_status in ['maintenance', 'disabled']:
                today = date.today()
                now_time = datetime.now().time()

                ongoing_reservations = Reservation.query.filter(
                    and_(
                        Reservation.table_id == table_id,
                        Reservation.status == 'confirmed',
                        or_(
                            Reservation.reservation_date > today,
                            and_(
                                Reservation.reservation_date == today,
                                Reservation.end_time > now_time
                            )
                        )
                    )
                ).count()

                if ongoing_reservations > 0:
                    status_map = {'maintenance': '维护', 'disabled': '禁用'}
                    return False, f"球台有正在进行的课程，无法设为{status_map[new_status]}状态"

            table.status = new_status
            table.updated_at = datetime.now()

            db.session.commit()
            return True, None

        except Exception as e:
            db.session.rollback()
            current_app.logger.error(f"Update table status error: {str(e)}")
            return False, "更新状态失败，请重试"

    @staticmethod
    def get_table_statistics(table_id):
        """
        获取球台使用统计

        Args:
            table_id: 球台ID

        Returns:
            dict: 统计信息
        """
        table = TableController.get_table_by_id(table_id)
        if not table:
            return {}

        today = date.today()
        week_start = today - timedelta(days=today.weekday())
        month_start = today.replace(day=1)

        # 今日统计
        today_reservations = Reservation.query.filter(
            and_(
                Reservation.table_id == table_id,
                Reservation.reservation_date == today
            )
        ).count()

        today_revenue = db.session.query(func.sum(Reservation.price)).filter(
            and_(
                Reservation.table_id == table_id,
                Reservation.reservation_date == today,
                Reservation.status == 'completed'
            )
        ).scalar() or 0

        # 本周统计
        week_reservations = Reservation.query.filter(
            and_(
                Reservation.table_id == table_id,
                Reservation.reservation_date >= week_start
            )
        ).count()

        week_revenue = db.session.query(func.sum(Reservation.price)).filter(
            and_(
                Reservation.table_id == table_id,
                Reservation.reservation_date >= week_start,
                Reservation.status == 'completed'
            )
        ).scalar() or 0

        # 本月统计
        month_reservations = Reservation.query.filter(
            and_(
                Reservation.table_id == table_id,
                Reservation.reservation_date >= month_start
            )
        ).count()

        month_revenue = db.session.query(func.sum(Reservation.price)).filter(
            and_(
                Reservation.table_id == table_id,
                Reservation.reservation_date >= month_start,
                Reservation.status == 'completed'
            )
        ).scalar() or 0

        # 总统计
        total_reservations = Reservation.query.filter_by(table_id=table_id).count()
        total_revenue = db.session.query(func.sum(Reservation.price)).filter(
            and_(
                Reservation.table_id == table_id,
                Reservation.status == 'completed'
            )
        ).scalar() or 0

        # 使用率统计（本月）
        total_hours_month = (today - month_start).days * 12  # 假设每天12小时营业

        # MySQL兼容的时长计算：使用duration_minutes字段
        used_hours_month = db.session.query(
            func.sum(Reservation.duration_minutes)
        ).filter(
            and_(
                Reservation.table_id == table_id,
                Reservation.reservation_date >= month_start,
                Reservation.status.in_(['completed', 'confirmed'])
            )
        ).scalar() or 0

        # 转换为小时
        used_hours_month = used_hours_month / 60

        usage_rate = (used_hours_month / total_hours_month * 100) if total_hours_month > 0 else 0

        return {
            'today_reservations': today_reservations,
            'today_revenue': float(today_revenue),
            'week_reservations': week_reservations,
            'week_revenue': float(week_revenue),
            'month_reservations': month_reservations,
            'month_revenue': float(month_revenue),
            'total_reservations': total_reservations,
            'total_revenue': float(total_revenue),
            'usage_rate': round(usage_rate, 2)
        }

    @staticmethod
    def batch_operation(table_ids, action):
        """
        批量操作球台

        Args:
            table_ids: 球台ID列表
            action: 操作类型

        Returns:
            tuple: (成功数量, 失败数量, 错误信息列表)
        """
        success_count = 0
        fail_count = 0
        errors = []

        for table_id in table_ids:
            try:
                table = TableController.get_table_by_id(table_id)
                if not table:
                    errors.append(f"球台ID {table_id} 不存在或无权限访问")
                    fail_count += 1
                    continue

                if action in ['available', 'maintenance', 'disabled']:
                    # 状态更新
                    success, error_msg = TableController.update_table_status(table_id, action)
                    if success:
                        success_count += 1
                    else:
                        errors.append(f"球台 {table.name}: {error_msg}")
                        fail_count += 1

                elif action == 'delete':
                    # 删除操作
                    success, error_msg = TableController.delete_table(table_id)
                    if success:
                        success_count += 1
                    else:
                        errors.append(f"球台 {table.name}: {error_msg}")
                        fail_count += 1

            except Exception as e:
                errors.append(f"球台ID {table_id}: {str(e)}")
                fail_count += 1

        return success_count, fail_count, errors

    @staticmethod
    def get_campus_table_summary(campus_id=None):
        """
        获取校区球台汇总统计

        Args:
            campus_id: 校区ID，None表示所有校区

        Returns:
            dict: 汇总统计
        """
        query = Table.query.filter(Table.status != 'deleted')

        if campus_id:
            query = query.filter(Table.campus_id == campus_id)
        elif current_user.is_campus_admin() and current_user.campus_id:
            query = query.filter(Table.campus_id == current_user.campus_id)

        total_tables = query.count()
        available_tables = query.filter(Table.status == 'available').count()
        maintenance_tables = query.filter(Table.status == 'maintenance').count()
        disabled_tables = query.filter(Table.status == 'disabled').count()

        return {
            'total_tables': total_tables,
            'available_tables': available_tables,
            'maintenance_tables': maintenance_tables,
            'disabled_tables': disabled_tables
        }